<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>发送 Cookie</title>
 </head>
 <body class="docs"><div id="layout">
  <div id="layout-content"><div id="function.setcookie" class="refentry">
 <div class="refnamediv">
  <h1 class="refname">setcookie</h1>
  <p class="verinfo">(PHP 4, PHP 5, PHP 7)</p><p class="refpurpose"><span class="refname">setcookie</span> &mdash; <span class="dc-title">发送 Cookie</span></p>

 </div>
 
 <div class="refsect1 description" id="refsect1-function.setcookie-description">
  <h3 class="title">说明</h3>
  <div class="methodsynopsis dc-description">
   <span class="methodname"><strong>setcookie</strong></span>
    ( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span>
   [, <span class="methodparam"><span class="type">string</span> <code class="parameter">$value</code><span class="initializer"> = &quot;&quot;</span></span>
   [, <span class="methodparam"><span class="type">int</span> <code class="parameter">$expire</code><span class="initializer"> = 0</span></span>
   [, <span class="methodparam"><span class="type">string</span> <code class="parameter">$path</code><span class="initializer"> = &quot;&quot;</span></span>
   [, <span class="methodparam"><span class="type">string</span> <code class="parameter">$domain</code><span class="initializer"> = &quot;&quot;</span></span>
   [, <span class="methodparam"><span class="type">bool</span> <code class="parameter">$secure</code><span class="initializer"> = false</span></span>
   [, <span class="methodparam"><span class="type">bool</span> <code class="parameter">$httponly</code><span class="initializer"> = false</span></span>
  ]]]]]] ) : <span class="type">bool</span></div>

  <p class="para rdfs-comment">
   <span class="function"><strong>setcookie()</strong></span> 定义了 Cookie，会和剩下的 HTTP 头一起发送给客户端。
   和其他 HTTP 头一样，必须在脚本产生任意输出<em class="emphasis">之前</em>发送 Cookie（由于协议的限制）。
   请在产生任何输出之前（包括 <em>&lt;html&gt;</em> 和 <em>&lt;head&gt;</em> 或者空格）调用本函数。
  </p>
  <p class="para">
   一旦设置 Cookie 后，下次打开页面时可以使用 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE</a></var></var> 读取。
   Cookie 值同样也存在于 <var class="varname"><var class="varname"><a href="reserved.variables.request.html" class="classname">$_REQUEST</a></var></var>。
  </p>
 </div>


 <div class="refsect1 parameters" id="refsect1-function.setcookie-parameters">
  <h3 class="title">参数</h3>
  <p class="para">
   <a href="http://www.faqs.org/rfcs/rfc6265" class="link external">&raquo;&nbsp;RFC 6265</a> 提供了 <span class="function"><strong>setcookie()</strong></span> 每个参数的参考标准。
   <dl>

    
     <dt>
<code class="parameter">name</code></dt>

     <dd>

      <p class="para">
       Cookie 名称。
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">value</code></dt>

     <dd>

      <p class="para">
       Cookie 值。
       这个值储存于用户的电脑里，请勿储存敏感信息。
       比如 <code class="parameter">name</code> 是 <em>&#039;cookiename&#039;</em>，
       可通过 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE['cookiename']</a></var></var> 获取它的值。
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">expire</code></dt>

     <dd>

      <p class="para">
       Cookie 的过期时间。
       这是个 Unix 时间戳，即 Unix 纪元以来（格林威治时间 1970 年 1 月 1 日 00:00:00）的秒数。
       也就是说，基本可以用 <span class="function"><a href="time.html" class="function">time()</a></span> 函数的结果加上希望过期的秒数。
       或者也可以用 <span class="function"><a href="mktime.html" class="function">mktime()</a></span>。
       <em>time()+60*60*24*30</em> 就是设置 Cookie 30 天后过期。
       如果设置成零，或者忽略参数， Cookie 会在会话结束时过期（也就是关掉浏览器时）。
      </p>
      <p class="para">
       <blockquote class="note"><p><strong class="note">Note</strong>: 
        <p class="para">
          你可能注意到了，<code class="parameter">expire</code> 使用 Unix 时间戳而非 <em>Wdy, DD-Mon-YYYY
         HH:MM:SS GMT</em> 这样的日期格式，是因为 PHP 内部作了转换。
        </p>
       </p></blockquote>
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">path</code></dt>

     <dd>

      <p class="para">
       Cookie 有效的服务器路径。
       设置成 <em>&#039;/&#039;</em> 时，Cookie 对整个域名 <code class="parameter">domain</code> 有效。
       
       如果设置成 <em>&#039;/foo/&#039;</em>， Cookie 仅仅对 <code class="parameter">domain</code> 中 <em>/foo/</em> 目录及其子目录有效（比如 <em>/foo/bar/</em>）。
       默认值是设置 Cookie 时的当前目录。
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">domain</code></dt>

     <dd>

      <p class="para">
       Cookie 的有效域名/子域名。
       设置成子域名（例如 <em>&#039;www.example.com&#039;</em>），会使 Cookie 对这个子域名和它的三级域名有效（例如 w2.www.example.com）。
       要让 Cookie 对整个域名有效（包括它的全部子域名），只要设置成域名就可以了（这个例子里是 <em>&#039;example.com&#039;</em>）。
      </p>
      <p class="para">
       旧版浏览器仍然在使用废弃的 <a href="http://www.faqs.org/rfcs/rfc2109" class="link external">&raquo;&nbsp;RFC 2109</a>，
       需要一个前置的点 <em>.</em> 来匹配所有子域名。
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">secure</code></dt>

     <dd>

      <p class="para">
       设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。
       设置成 <strong><code>TRUE</code></strong> 时，只有安全连接存在时才会设置 Cookie。
       如果是在服务器端处理这个需求，程序员需要仅仅在安全连接上发送此类 Cookie
       （通过 <var class="varname"><var class="varname"><a href="reserved.variables.server.html" class="classname">$_SERVER["HTTPS"]</a></var></var> 判断）。
      </p>
     </dd>

    
    
     <dt>
<code class="parameter">httponly</code></dt>

     <dd>

      <p class="para">
       设置成 <strong><code>TRUE</code></strong>，Cookie 仅可通过 HTTP 协议访问。
       这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。
       要有效减少 XSS 攻击时的身份窃取行为，可建议用此设置（虽然不是所有浏览器都支持），不过这个说法经常有争议。
       PHP 5.2.0 中添加。
       <strong><code>TRUE</code></strong> 或 <strong><code>FALSE</code></strong>
      </p>
     </dd>

    
   </dl>

  </p>
 </div>


 <div class="refsect1 returnvalues" id="refsect1-function.setcookie-returnvalues">
  <h3 class="title">返回值</h3>
  <p class="para">
   如果在调用本函数以前就产生了输出，<span class="function"><strong>setcookie()</strong></span> 会调用失败并返回 <strong><code>FALSE</code></strong>。
   如果 <span class="function"><strong>setcookie()</strong></span> 成功运行，返回 <strong><code>TRUE</code></strong>。当然，它的意思并非用户是否已接受 Cookie。
  </p>
 </div>


 <div class="refsect1 examples" id="refsect1-function.setcookie-examples">
  <h3 class="title">范例</h3>
  <p class="para">
   发送 Cookie 的几个例子：
   <div class="example" id="header-register-callback.example.basic">
    <p><strong>Example #1 <span class="function"><strong>setcookie()</strong></span> 发送例子</strong></p>
    <div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br />$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'something&nbsp;from&nbsp;somewhere'</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">);&nbsp;&nbsp;</span><span style="color: #FF8000">/*&nbsp;1&nbsp;小时过期&nbsp;&nbsp;*/<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
    </div>

   </div>
  </p>
  <p class="para">
   注意：在发送 Cookie 时，值的部分会被自动 urlencode 编码。收到 Cookie 时，会自动解码，并赋值到可变的 Cookie 名称上。
   如果不想被编码，可以使用 <span class="function"><a href="setrawcookie.html" class="function">setrawcookie()</a></span> 代替——如果你的 PHP 版本是 5 及以上。
   在脚本里查看我们的测试 Cookie 的内容，使用下面的一个例子：
  </p>
  <p class="para">
   <div class="informalexample">
    <div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;打印一个单独的&nbsp;Cookie<br /></span><span style="color: #007700">echo&nbsp;</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">];<br /><br /></span><span style="color: #FF8000">//&nbsp;&nbsp;debug/test&nbsp;查看所有&nbsp;Cookie&nbsp;的另一种方式<br /></span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
    </div>

   </div>
  </p>
  <p class="para">
   <div class="example" id="example-5504">
    <p><strong>Example #2 <span class="function"><strong>setcookie()</strong></span> 删除例子</strong></p>
    <div class="example-contents"><p>
     要删除一个 Cookie，应该设置过期时间为过去，以触发浏览器的删除机制。
     下面的例子展示了如何删除上个例子里的 Cookie：
    </p></div>
    <div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;设置过期时间为一个小时前<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">""</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()&nbsp;-&nbsp;</span><span style="color: #0000BB">3600</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">""</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()&nbsp;-&nbsp;</span><span style="color: #0000BB">3600</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
    </div>

   </div>
  </p>
  <p class="para">
   <div class="example" id="example-5505">
    <p><strong>Example #3 <span class="function"><strong>setcookie()</strong></span> 和数组</strong></p>
    <div class="example-contents"><p>
     通过带 array 标记的 Cookie 名称，也可以把 Cookie 设置成数组。
     如果有数组元素，可以把它放进 Cookie 里；
     脚本接收到时，Cookie 名称里的值会是一个数组：
    </p></div>
    <div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;设置&nbsp;Cookie<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[three]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookiethree"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[two]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookietwo"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[one]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookieone"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">//&nbsp;网页刷新后，打印出以下内容<br /></span><span style="color: #007700">if&nbsp;(isset(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">]))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">]&nbsp;as&nbsp;</span><span style="color: #0000BB">$name&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">&nbsp;:&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #DD0000">&nbsp;&lt;br&nbsp;/&gt;\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
    </div>

    <div class="example-contents"><p>以上例程会输出：</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
three : cookiethree
two : cookietwo
one : cookieone
</pre></div>
    </div>
   </div>
  </p>
 </div>


 <div class="refsect1 changelog" id="refsect1-function.setcookie-changelog">
  <h3 class="title">更新日志</h3>
  <p class="para">
   <table class="doctable informaltable">
    
     <thead>
      <tr>
       <th>版本</th>
       <th>说明</th>
      </tr>

     </thead>

     <tbody class="tbody">
      <tr>
       <td>5.5.0</td>
       <td>
        发送给客户端的 Set-Cookie 头现在会包含 Max-Age 属性。
       </td>
      </tr>

      <tr>
       <td>5.2.0</td>
       <td>
        添加 <code class="parameter">httponly</code> 参数。
       </td>
      </tr>

     </tbody>
    
   </table>

  </p>
 </div>


 <div class="refsect1 notes" id="refsect1-function.setcookie-notes">
  <h3 class="title">注释</h3>
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    要在调用本函数前输出内容，可以使用输出缓冲：让输出的内容在服务器里缓冲起来，
    直至真正发送给浏览器。
    可在脚本里调用 <span class="function"><a href="ob_start.html" class="function">ob_start()</a></span> 和 <span class="function"><a href="ob_end_flush.html" class="function">ob_end_flush()</a></span>，
    或设置 <em>output_buffering</em> <var class="filename">php.ini</var> 或服务器配置文件里的配置指令。
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    如果 PHP 指令 <a href="ini.core.html#ini.register-globals" class="link">register_globals</a>
    设置成 <em>on</em>，Cookie 值会自动设置成变量。
    下面的例子里会存在 <var class="varname"><var class="varname">$TestCookie</var></var>。
    我们推荐你使用 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE</a></var></var>。
   </p>
  </p></blockquote>
  <p class="para">
   注意避坑：
   <ul class="itemizedlist">
    <li class="listitem">
     <span class="simpara">
      在页面（ Cookie 可见的页面）下次刷新前，Cookie 不会生效。
      测试 Cookie 是否已经成功设置，需要在下次页面加载时、Cookie 过期前检测。
      过期时间是通过 <code class="parameter">expire</code> 参数设置的。
      直接调用 <em>print_r($_COOKIE);</em> 调试检测 Cookie 是个很好的方式。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      为同一个参数再次设置 Cookie 前，必须先把它删掉。
      如果参数的值是空 string 或 <strong><code>FALSE</code></strong>，并且其他参数和上次调用 setcookie 仍旧一样，
      则指定的名称会被远程客户端删除。
      内部的实现是：将值设置成 &#039;deleted&#039;，并且过期时间是一年前。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      因为设置值成 <strong><code>FALSE</code></strong> 会导致 Cookie 被删除，所以要避免使用布尔值。
      代替方式：<em class="emphasis">0</em> 是 <strong><code>FALSE</code></strong>，<em class="emphasis">1</em> 是 <strong><code>TRUE</code></strong>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      Cookie 名称可以设置成数组名称，PHP 脚本里会是数组，
      但用户系统里储存的是单独分开的 Cookie。 
      可以考虑使用 <span class="function"><a href="explode.html" class="function">explode()</a></span> 为一个 Cookie 设置多个名称和值。
      不建议将 <span class="function"><a href="serialize.html" class="function">serialize()</a></span> 用于此处，因为它会导致安全漏洞。
     </span>
    </li>
   </ul>
  </p>
  <p class="simpara">
   多次调用 <span class="function"><strong>setcookie()</strong></span> 会按调用顺序执行。
  </p>
 </div>


 <div class="refsect1 seealso" id="refsect1-function.setcookie-seealso">
  <h3 class="title">参见</h3>
  <p class="para">
   <ul class="simplelist">
    <li class="member"><span class="function"><a href="header.html" class="function" rel="rdfs-seeAlso">header()</a> - 发送原生 HTTP 头</span></li>
    <li class="member"><span class="function"><a href="setrawcookie.html" class="function" rel="rdfs-seeAlso">setrawcookie()</a> - 发送未经 URL 编码的 cookie</span></li>
    <li class="member"><a href="features.cookies.html" class="link">Cookie 章节</a></li>
    <li class="member"><a href="http://www.faqs.org/rfcs/rfc6265" class="link external">&raquo;&nbsp;RFC 6265</a></li>
    <li class="member"><a href="http://www.faqs.org/rfcs/rfc2109" class="link external">&raquo;&nbsp;RFC 2109</a></li>
   </ul>
  </p>
 </div>


</div></div></div></body></html>